#include "dictionarymediator.h"
#include "preferences.h"
#include "word.h"
#include "dictionary.h"
#if DEBUG
	#include <QDebug>
#endif

using namespace qWordCards;

DictionaryMediator::DictionaryMediator(const Dictionary* const d) : QObject(0), _dictionary(d) {
	if (d == NULL) {
		throw "Argument is NULL";
	}
	
	QObject::connect(&Preferences::suspendedWords, SIGNAL(sg_WordAdded(QString)), this, SLOT(sl_WordAddedToSuspendedList(QString)));
	QObject::connect(&Preferences::suspendedWords, SIGNAL(sg_WordRemoved(QString)), this, SLOT(sl_WordRemovedFromSuspendedList(QString)));
	
	QObject::connect(&Preferences::favouriteWords, SIGNAL(sg_WordAdded(QString)), this, SLOT(sl_WordAddedToFavouriteList(QString)));
	QObject::connect(&Preferences::favouriteWords, SIGNAL(sg_WordRemoved(QString)), this, SLOT(sl_WordRemovedFromFavouriteList(QString)));
	
	QObject::connect(&Preferences::forbiddenWords, SIGNAL(sg_WordAdded(QString)), this, SLOT(sl_WordAddedToForbiddenList(QString)));
	QObject::connect(&Preferences::forbiddenWords, SIGNAL(sg_WordRemoved(QString)), this, SLOT(sl_WordRemovedFromForbiddenList(QString)));
	
	QObject::connect(_dictionary, SIGNAL(sg_Reloaded), this, SLOT(RebuildLists));
	
	RebuildLists();
}

DictionaryMediator::~DictionaryMediator() {
	Preferences::suspendedWords.disconnect(this);
	Preferences::favouriteWords.disconnect(this);
	Preferences::forbiddenWords.disconnect(this);
}

void DictionaryMediator::RebuildLists() {
	if (_dictionary == NULL) {throw "There is no binded dictionary";}

	_suspendedWords.clear();
	_favouriteWords.clear();
	_forbiddenWords.clear();
	_regularWords.clear();

	int listSize = _dictionary->GetWordsList().size();
	QString w = "";
	for (int i = 0; i < listSize; ++i) {
		w = _dictionary->GetWordsList().at(i);

		if (Preferences::suspendedWords.Contains(w)) {
			_suspendedWords.insert(w);
		} else if (Preferences::forbiddenWords.Contains(w)) {
			_forbiddenWords.insert(w);
		} else if (Preferences::favouriteWords.Contains(w)) {
			_favouriteWords.insert(w);
		} else {
			_regularWords.insert(w);
		}
	}
}

Word DictionaryMediator::GetWord() const {
	// TODO: implement

	return Word(); // stub
}

int DictionaryMediator::GetFavouriteWordsCount() const {
	return _favouriteWords.size();
}

int DictionaryMediator::GetForbiddenWordsCount() const {
	return _forbiddenWords.size();
}

int DictionaryMediator::GetRegularWordsCount() const {
	return _regularWords.size();
}

Dictionary* DictionaryMediator::GetDictionary() const {
	return _dictionary;
}

void DictionaryMediator::sl_WordAddedToSuspendedList(QString s) {
	if (_suspendedWords.contains(s)) {
#if DEBUG
		qDebug() << QString("DictionaryMediator::sl_WordAddedToSuspendedList. Word is already in _suspendedWords list: \"%1\"").arg(s);
#endif
		return;
	}
	if (_forbiddenWords.contains(s)) {
		_forbiddenWords.remove(s);
		_suspendedWords.insert(s);
	} else if (_favouriteWords.contains(s)) {
		_favouriteWords.remove(s);
		_suspendedWords.insert(s);
	} else if (_regularWords.contains(s)) {
		_regularWords.remove(s);
		_suspendedWords.insert(s);
	} else {
#if DEBUG
		qDebug() << QString("DictionaryMediator::sl_WordAddedToSuspendedList. Word not contained in any list: \"%1\"").arg(s);
#endif
	}
}

void DictionaryMediator::sl_WordRemovedFromSuspendedList(QString s) {
	if (!_suspendedWords.contains(s)) {
#if DEBUG
		qDebug();
#endif
		return;
	}
	_suspendedWords.remove(s);
	if (Preferences::forbiddenWords.Contains(s)) {
		_forbiddenWords.insert(s);
	} else if (Preferences::favouriteWords.Contains(s)) {
		_favouriteWords.insert(s);
	} else {
		_regularWords.insert(s);
	}
}

void DictionaryMediator::sl_WordAddedToFavouriteList(QString s) {
	if (_favouriteWords.contains(s)) {
#if DEBUG
		qDebug() << QString("WARNING: DictionaryMediator::sl_WordAddedToFavouriteList. Word is already in _favouriteWords list: \"%1\"").arg(s);
#endif
		return;
	}

	if (_suspendedWords.contains(s)) {
		return;
	} else if (_forbiddenWords.contains(s)) {
#if DEBUG
		qDebug() << QString("WARNING: DictionaryMediator::sl_WordAddedToFavouriteList. Word is in _forbiddenWords list: \"%1\", but must not be.").arg(s);
#endif
		_forbiddenWords.remove(s);
		_favouriteWords.insert(s);
	} else if (_regularWords.contains(s)) {
		_regularWords.remove(s);
		_favouriteWords.insert(s);
	}
}

void DictionaryMediator::sl_WordRemovedFromFavouriteList(QString s) {
	if (_suspendedWords.contains(s)) {
		return;
	}

	if (!_favouriteWords.contains(s)) {
#if DEBUG
		qDebug() << QString("WARNING: DictionaryMediator::sl_WordRemovedFromFavouriteList. Word is not in _favouriteWords list: \"%1\"").arg(s);
#endif
		return;
	}

	_favouriteWords.remove(s);
	if (Preferences::forbiddenWords.Contains(s)) {
		_forbiddenWords.insert(s);
	} else {
		_regularWords.insert(s);
	}
}

void DictionaryMediator::sl_WordAddedToForbiddenList(QString s) {
	if (_forbiddenWords.contains(s)) {
#if DEBUG
		qDebug() << QString("WARNING: DictionaryMediator::sl_WordAddedToForbiddenList. Word is already in _forbiddenWords list: \"%1\"").arg(s);
#endif
		return;
	}

	if (_suspendedWords.contains(s)) {
		return;
	} else if (_favouriteWords.contains(s)) {
#if DEBUG
		qDebug() << QString("WARNING: DictionaryMediator::sl_WordAddedToForbiddenList. Word is in _forbiddenWords list: \"%1\", but must not be.").arg(s);
#endif
		_favouriteWords.remove(s);
		_forbiddenWords.insert(s);
	} else if (_regularWords.contains(s)) {
		_regularWords.remove(s);
		_forbiddenWords.insert(s);
	}
}

void DictionaryMediator::sl_WordRemovedFromForbiddenList(QString s) {
	if (_suspendedWords.contains(s)) {
		return;
	}

	if (!_forbiddenWords.contains(s)) {
#if DEBUG
		qDebug() << QString("WARNING: DictionaryMediator::sl_WordRemovedFromForbiddenList. Word is not in _forbiddenWords list: \"%1\"").arg(s);
#endif
		return;
	}

	_forbiddenWords.remove(s);
	if (Preferences::favouriteWords.Contains(s)) {
		_favouriteWords.insert(s);
	} else {
		_regularWords.insert(s);
	}
}
